/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package designpattern.behavioral_patterns;

import java.util.Vector;

/**
 *
 * @author tandaica0612
 */
public class ObserverPattern {
    abstract class Subject{
        private Vector _observers = new Vector();
        public void attach(Observer observer){
            _observers.add(observer);
        }
        public void detach(Observer observer){
            _observers.remove(observer);
        }
        //
        public void notifyUpdate(){
            for (Object object : _observers) {
                ((Observer)object).update();
            }

        }
    }
    //
    class ConcreteSubject extends Subject{
        private String _subjectState;

        public String getSubjectState() {
            return _subjectState;
        }

        public void setSubjectState(String _subjectState) {
            this._subjectState = _subjectState;
        }
        
    }
    //
    abstract class Observer{
        public abstract void update();
    }
    //
    class ConcreteObserverA extends Observer{
        private String _name;
        private String _observerState;
        private ConcreteSubject _concreteSubject;
        public ConcreteObserverA(String _name, ConcreteSubject _concreteSubject) {
            this._name = _name;
            this._concreteSubject = _concreteSubject;
        }                
        @Override
        public void update() {
            this._observerState = _concreteSubject.getSubjectState();
            System.out.printf("Observer "+ _name +"'s new state is \"" + _observerState + "\"\n");
        }
        //
        public ObserverPattern.ConcreteSubject getConcreteSubject() {
            return _concreteSubject;
        }

        public void setConcreteSubject(ObserverPattern.ConcreteSubject _concreteSubject) {
            this._concreteSubject = _concreteSubject;
        }         
    }
    //
    
    class ConcreteObserverB extends Observer{
        private String _name;
        private String _observerState;
        private ConcreteSubject _concreteSubject;
        public ConcreteObserverB(String _name, ConcreteSubject _concreteSubject) {
            this._name = _name;
            this._concreteSubject = _concreteSubject;
        }
        
        @Override
        public void update() {
            this._observerState = _concreteSubject.getSubjectState();
            System.out.printf("Observer "+ _name +"'s new state is \"" + _observerState + "\"\n");
        }
        public ObserverPattern.ConcreteSubject getConcreteSubject() {
            return _concreteSubject;
        }

        public void setConcreteSubject(ObserverPattern.ConcreteSubject _concreteSubject) {
            this._concreteSubject = _concreteSubject;
        }        
    }
    //
    public static void main(String arg[]){
        ObserverPattern pattern = new ObserverPattern();
        //
        ConcreteSubject subject = pattern.new ConcreteSubject();
        subject.attach(pattern.new ConcreteObserverA("A", subject));
        subject.attach(pattern.new ConcreteObserverB("B", subject));
        subject.attach(pattern.new ConcreteObserverA("A2", subject));
        subject.attach(pattern.new ConcreteObserverA("B2", subject));
        subject.setSubjectState("123");
        subject.notifyUpdate();
        
    }
}
/*
Observer A's new state is "123"
Observer B's new state is "123"
Observer A2's new state is "123"
Observer B2's new state is "123"
 * */